package com.itlong.cloud.intercept;


import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.enumerate.CloudDeviceErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 * <desc>
 *    获取授权文件拦截器
 * </desc>
 *
 * @author: chengshican
 *  @Date: 2020-08-18 10:19
 *
 */



@Aspect
@Component
@Order(0)
public class whiteListAuthIntercept {
    // 定义一个切入点
    //@Pointcut("(execution(* com.itlong.cloud.controller.CloudEntranceController.*(..)) || execution(* com.itlong.cloud.controller.CloudTalkController.*(..))) && @annotation(com.itlong.cloud.annotation.UnParamEncrypt)")

    @Pointcut("execution(* com.itlong.cloud.controller.CloudEntranceController.*(..))  && @annotation(com.itlong.cloud.annotation.UnParamEncrypt)")
    public void excudeService(){}


    @Value("${"+ PlatformConstants.CLOUD_TALK_TOKEN_DONTINTERCEPT+"}")
    String dontIntercept;

    @Value("${" + PlatformConstants.CLOUD_ELEVATOR_AESKEY + "}")
    private  String cloudElevatorAeskey; //AES加密KEY
    @Value("${" + PlatformConstants.CLOUD_ELEVATOR_MD5KEY + "}")
    private  String cloudElevatorMd5key;  //MD5加密KEY

    @Around("excudeService()")
    public Object handleParam(ProceedingJoinPoint thisJoinPoint) throws Throwable{
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        //获取所有的请求参数键值对并根据加密方案进行校验通信加密是否正常
        Map map = request.getParameterMap();
        int encryptionAbility = 0; //默认未采用加密方案
        if (map.containsKey("encryptionAbility")&&StringUtils.isNotBlank(request.getParameter("encryptionAbility"))){
            encryptionAbility = Integer.parseInt(request.getParameter("encryptionAbility"));
        }

            String encrypScript = "";
            if (map.containsKey("encrypScript")) {   //是否携带加密串，检测预防异常
                encrypScript = request.getParameter("encrypScript").toString();
            }
            if (StringUtils.isBlank(encrypScript)) { //加密串未携带，参数异常
                return getEncryptResult(new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode()), encryptionAbility);
            } else {
                //验证MD5是否正确
                String content = StringHandlerUtil.replaceBlank(encrypScript.substring(0, encrypScript.length() - 32));
                String md5 = encrypScript.substring(encrypScript.length() - 32, encrypScript.length());
                if (!Md5EncryptUtil.md5(content + cloudElevatorMd5key).toUpperCase().equals(md5)) {
                    return getEncryptResult(new MessageVO(CloudDeviceErrorCodeEnum.CLOUD_ELEVATOR_ILLEGAL_REQUEST.getErrorCode()), encryptionAbility);
                }

                //解密
                String encryptResult = URLDecoder.decode(DesEncryptUtil.aesDecrypt(content, cloudElevatorAeskey).replaceAll("%0A", ""), "UTF-8");
                Map<String, Object> params = JsonUtil.toObject(encryptResult, HashMap.class);
                request.setAttribute("params", params);
                //加密
                Object result = thisJoinPoint.proceed();
                MessageVO messageVO = (MessageVO) result;
                return result;


        }

    }

    /**
     * <desc>
     *      返回加密内容
     * </desc>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2018/04/10
     */
    private Map<String,Object> getEncryptResult(Object result,Integer encryptionAbility) throws Exception {
        MessageVO messageVO = (MessageVO)result;
        String encryptResult = DesEncryptUtil.aesEncrypt(JsonUtil.toJSON(messageVO),cloudElevatorAeskey,cloudElevatorMd5key);
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("encryptionAbility",encryptionAbility); //加密方案需要参与响应结果加密
        resultMap.put("encrypScript", encryptResult);
        return resultMap;
    }
}
